2023/12/232355字符
切片类型(动态数组)
- 切片的本质就是指向了一个底层数组,随着容量的增大而不停的改变新的底层数组,从而实现扩容;
- 如果已经有了数值,我们也可以直接创建切片。
package main
import "fmt"
func main() {
var sli1 = make([]int, 3, 8)
fmt.Println(sli1) //--> [0 0 0]
fmt.Println(len(sli1), cap(sli1)) //--> 3 8
var sli2 = append(sli1, 3, 4)
fmt.Println(sli2) //--> [0 0 0 3 4]
var sli3 = [] int{5, 6} //--> 不指定长度是一个 slice
var sli4 = append(sli2, sli3...)
fmt.Println(sli4) //--> [0 0 0 3 4 5 6]
}
内存分析
切片的每一项是引用关系,改变数据,被引用切片也相应做出改变
package main
import "fmt"
func main() {
arr := [10]int{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
s1 := arr[:5]
s2 := arr[3:8]
s3 := arr[5:]
s4 := arr[:]
fmt.Printf("%p, %p, %p\n", &arr, s1, s4) // arr, s1, s4 指向同一个地址
fmt.Println(len(s1), cap(s1)) //--> 5 10
fmt.Println(len(s2), cap(s2)) //--> 5 7
fmt.Println(len(s3), cap(s3)) //--> 5 5
fmt.Println(len(s4), cap(s4)) //--> 10 10
// 操作数组,切片数据发生改变
arr[3] = 100
fmt.Println(s1, s2, s3, s4) //--> 1 2 3 100 5] [100 5 6 7 8] [6 7 8 9 10] [1 2 3 100 5 6 7 8 9 10]
// 操作切片,数组数据也会被更改
s1[4] = 200
fmt.Println(arr) //--> [1 2 3 100 200 6 7 8 9 10]
// 切片添加内容,数组也会被改变
s1 = append(s1, 1, 1, 1)
fmt.Println(arr, s1, s2) //--> [1 2 3 100 200 1 1 1 9 10] [1 2 3 100 200 1 1 1] [100 200 1 1 1]
// 超出数组长度,go 会新开辟一个数组地址,与原先的数组就没关系了
s1 = append(s1, 2, 2, 2, 2, 2)
fmt.Println(arr, s1) //--> [1 2 3 100 200 1 1 1 9 10] [1 2 3 100 200 1 1 1 2 2 2 2 2]
fmt.Printf("%p, %p\n", &arr, s1) //--> 0xc00001c050, 0xc000104000
}
copy 深度克隆
package main
import "fmt"
func main() {
s1 := []int{1, 2, 3, 4}
s2 := []int{5, 6, 7}
copy(s1, s2)
fmt.Println(s1, s2) //--> [5 6 7 4] [5 6 7]
s3 := []int{1, 2, 3, 4}
s4 := []int{5, 6, 7}
copy(s4, s3[2:])
fmt.Println(s3, s4) //--> [1 2 3 4] [3 4 7]
}
排序
package main
import (
"fmt"
"sort"
)
func main() {
var sli = []int{ 3, 1, 6, 9, 4 }
sort.Ints(sli)
fmt.Println(sli) //--> [1 3 4 6 9]
}